/* Copyright (c) 2006, 2009, Carl Burch. License information is located in the
 * com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */
 
package com.cburch.logisim.std.io;

import java.awt.Color;
import java.awt.Graphics;

import com.cburch.logisim.data.Attribute;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.data.Value;
import com.cburch.logisim.instance.InstanceDataSingleton;
import com.cburch.logisim.instance.InstanceFactory;
import com.cburch.logisim.instance.InstancePainter;
import com.cburch.logisim.instance.InstanceState;
import com.cburch.logisim.instance.Port;
import com.cburch.logisim.util.IntegerFactory;
import com.cburch.logisim.util.Strings;

public class SevenSegment extends InstanceFactory {
    static Bounds[] SEGMENTS = null;
    static Color OFF_COLOR = null;
    
    public SevenSegment() {
        super("7-Segment Display", Strings.getter("sevenSegmentComponent", Strings.stdSource));
        setAttributes(new Attribute[] { Io.ATTR_COLOR },
                new Object[] { new Color(240, 0, 0) });
        setOffsetBounds(Bounds.create(-5, 0, 40, 60));
        setIconName("7seg.gif");
        setPorts(new Port[] {
                new Port(20,  0, Port.INPUT, 1),
                new Port(30,  0, Port.INPUT, 1),
                new Port(20, 60, Port.INPUT, 1),
                new Port(10, 60, Port.INPUT, 1),
                new Port( 0, 60, Port.INPUT, 1),
                new Port(10,  0, Port.INPUT, 1),
                new Port( 0,  0, Port.INPUT, 1),
                new Port(30, 60, Port.INPUT, 1),
            });
    }

    public void propagate(InstanceState state) {
        int summary = 0;
        for(int i = 0; i < 8; i++) {
            Value val = state.getPort(i);
            if(val == Value.TRUE) summary |= 1 << i;
        }
        Object value = IntegerFactory.create(summary);
        InstanceDataSingleton data = (InstanceDataSingleton) state.getData();
        if(data == null) {
            state.setData(new InstanceDataSingleton(value));
        } else {
            data.setValue(value);
        }
    }
    
    public void paintInstance(InstancePainter painter) {
        drawBase(painter);
    }
    
    static void drawBase(InstancePainter painter) {
        ensureSegments();
        InstanceDataSingleton data = (InstanceDataSingleton) painter.getData();
        int summ = (data == null ? 0 : ((Integer) data.getValue()).intValue());
        
        Bounds bds = painter.getBounds();
        int x = bds.getX() + 5;
        int y = bds.getY();

        Graphics g = painter.getGraphics();
        Color color = (Color) painter.getAttributeValue(Io.ATTR_COLOR);
        painter.drawBounds();
        g.setColor(Color.DARK_GRAY);
        for(int i = 0; i <= 7; i++) {
            if(painter.getShowState()) {
                g.setColor(((summ >> i) & 1) == 1 ? color : OFF_COLOR);
            }
            if(i < 7) {
                Bounds seg = SEGMENTS[i];
                g.fillRect(x + seg.getX(), y + seg.getY(), seg.getWidth(), seg.getHeight());
            } else {
                g.fillOval(x + 28, y + 48, 5, 5); // draw decimal point
            }
        }
        painter.drawPorts();
    }
    
    static void ensureSegments() {
        if(SEGMENTS == null) {
            OFF_COLOR = new Color(220, 220, 220);
            SEGMENTS = new Bounds[] {
                    Bounds.create( 3,  8, 19,  4),
                    Bounds.create(23, 10,  4, 19),
                    Bounds.create(23, 30,  4, 19),
                    Bounds.create( 3, 47, 19,  4),
                    Bounds.create(-2, 30,  4, 19),
                    Bounds.create(-2, 10,  4, 19),
                    Bounds.create( 3, 28, 19,  4)
            };
        }
    }
}
